package gui;

/**
 *
 * @author Raman
 */
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ObjectInputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Vector;

public class ChatInterface extends JFrame implements ActionListener {

  Timer timer = new Timer(3000, new TimerAction());
  private JLabel chatRoomLabel, onlineUsersLabel;
  private JTextArea usersRoom, chatRoom;
  private JTextField msgField;
  private JButton sendButton, logoutButton;
  
  //User Info-----------------------------------------
  private String userName;
  private int messageCount = 0;
//    ScrollPanes----------------------------------------
  JScrollPane textMsgPane;
  JScrollPane userListPane;
  JScrollPane msgFieldPane;
//    Layout stuff------------------------------------------------------------
  private GridBagLayout gbl;
  private GridBagConstraints gbc;
// Main Stuff----------------------------------------------------------------   
  private JPanel mainPanel;
//    Networking stuff
  private Socket toServer;
  private ObjectInputStream streamFromServer;
  private PrintStream streamToServer;
  private String address = "127.0.0.1";
  private int port = 4000;

  public ChatInterface(String userName) {
    super("ChatApp: " + userName);
    this.userName = userName;
    initComponents();
  }

  private void initComponents() {
    gbl = new GridBagLayout();
    gbc = new GridBagConstraints();

    mainPanel = new JPanel();
    mainPanel.setLayout(gbl);

//        Labels--------------------------------------------------------------
    gbc.gridx = 0;
    gbc.gridy = 0;
    chatRoomLabel = new JLabel("Chat Room", SwingConstants.LEFT);
    mainPanel.add(chatRoomLabel, gbc);
//        --------------------------------------------------------------
    gbc.gridx = 1;
    gbc.gridy = 0;
    onlineUsersLabel = new JLabel("Online Users", SwingConstants.LEFT);
    mainPanel.add(onlineUsersLabel, gbc);

//        CHAT ROOM WINDOW ----------------------------------------------------
    gbc.gridx = 0;
    gbc.gridy = 1;
    gbc.gridwidth = 1;
    gbc.gridheight = 1;
    gbc.weightx = 1;
    gbc.weighty = 1;
    chatRoom = new JTextArea(25, 35);
    chatRoom.setEditable(false);
    textMsgPane = new JScrollPane(chatRoom, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    mainPanel.add(textMsgPane, gbc);

//        USER WINDOW-----------------------------------------------------------
    gbc.gridx = 1;
    gbc.gridy = 1;
    gbc.weightx = 1;
    gbc.weighty = 1;
    gbc.gridwidth = 1;
    gbc.gridheight = 1;
    usersRoom = new JTextArea(25, 10);
    usersRoom.setEditable(false);
    userListPane = new JScrollPane(usersRoom, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    mainPanel.add(userListPane, gbc);

//        USER MSG FIELD--------------------------------------------------------
    gbc.gridx = 0;
    gbc.gridy = 2;
    gbc.gridwidth = 1;
    gbc.gridheight = 1;
    gbc.weightx = 1;
    gbc.weighty = 1;
    msgField = new JTextField(35);
    msgFieldPane = new JScrollPane(msgField, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    mainPanel.add(msgFieldPane, gbc);
    //--------------------------------------------------------------
    gbc.gridx = 1;
    gbc.gridy = 2;
    sendButton = new JButton("SEND");
    sendButton.setFocusable(true);
    sendButton.setMnemonic(KeyEvent.VK_S);
    mainPanel.add(sendButton, gbc);
    sendButton.addActionListener(this);
    sendButton.setActionCommand("send");

    //--------------------------------------------------------------
    gbc.gridx = 0;
    gbc.gridy = 3;
    logoutButton = new JButton("Log Out");
    logoutButton.setMnemonic(KeyEvent.VK_L);
    mainPanel.add(logoutButton, gbc);
    logoutButton.addActionListener(this);
    logoutButton.setActionCommand("logout");

    //------------------------------------------------------------
    getContentPane().add(mainPanel);

    //Adding a  windowListener to the window----------------------
    this.addWindowListener(new WindowAdapter() {

      @Override
      public void windowClosing(WindowEvent event) {
        try {
        System.out.println("Window Closing Event Performed.");  
        toServer = new Socket(address, port);
        streamFromServer = new ObjectInputStream(toServer.getInputStream());
        streamToServer = new PrintStream(toServer.getOutputStream());
        streamToServer.println("User Logout");
        streamToServer.println(userName);

        } catch (Exception ex) {
          System.out.println("Window Closing Event: " + ex);
          ex.printStackTrace();
        }
      }
    });

    //Frame stuff----------------------------------------------------
    setSize(new Dimension(590, 600));
    setVisible(true);
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//       Initialize the timer 
    timer.start();
  }

  @Override
  public void actionPerformed(ActionEvent event) {

    if (event.getActionCommand().equals("logout")) {
      try {
        
        System.out.println("LogOut Event Performed.");  
        toServer = new Socket(address, port);
        streamFromServer = new ObjectInputStream(toServer.getInputStream());
        streamToServer = new PrintStream(toServer.getOutputStream());
        streamToServer.println("User Logout");
        streamToServer.println(userName);
       
      } catch (Exception ex) {
        System.out.println("Logout Exception " + ex);
      }
      //close the current window
      this.dispose();
    }

    if (event.getActionCommand().equals("send")) {  
      try {
        toServer = new Socket(address, port);
        streamFromServer = new ObjectInputStream(toServer.getInputStream());
        streamToServer = new PrintStream(toServer.getOutputStream());
        
        String message = msgField.getText();
        streamToServer.println(userName + ":" + message);
        msgField.setText("");
        //Read the reply from the Server 
        
        Vector userMsg = (Vector) streamFromServer.readObject();
        System.out.println("User Messages " + userMsg);
        chatRoom.setText("");
        for (int i = 0; i < userMsg.size(); i++) {
          chatRoom.append((String) userMsg.elementAt(i));
          chatRoom.append("\n");
        }//END OF FOR 
      } catch (Exception ex) {
        System.out.println(ex);
        ex.printStackTrace();
      }
    }
    
  }//END OF actionPerformed


  /** TimerAction is used to perform the update of UserList and MessageList */
  class TimerAction implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent event) {
      try {

        toServer = new Socket(address, port);
        streamFromServer = new ObjectInputStream(toServer.getInputStream());
        streamToServer = new PrintStream(toServer.getOutputStream());

        //send a message to Server
        streamToServer.println("From Timer");
      
      
        Vector msgList = (Vector) streamFromServer.readObject();
        System.out.println("MessageList " + msgList); 

        //show the users online
        chatRoom.setText("");
        if(!(msgList.isEmpty())){
          for (int i = 0; i < msgList.size(); i++) {
            chatRoom.append((String) msgList.elementAt(i));
            chatRoom.append("\n");
          }
        }
        
        Vector userList = null ;
        if((userList = (Vector)streamFromServer.readObject()).contains("userList")){
          System.out.println("Online Users" + userList);
          usersRoom.setText("");
          for(int i=1 ; i < userList.size() ; i++){
            if(!(userList.elementAt(i).equals(userName))){
              usersRoom.append((String)userList.elementAt(i));
              usersRoom.append("\n");
              }
            }
          }
        
      } catch (Exception ex) {
        System.out.println("Timer Exception ");
        ex.printStackTrace();
      }
    }
  }
  
}
